//
// Created on 2023/4/19.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".

#include <js_native_api.h>
#include <js_native_api_types.h>
#include "InputNapi.h"
#include "napi/adapter/EditBoxHandler.h"
#include "napi/common/OhosLog.h"


napi_value InputNapi::textInputOnBeginCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 1;
    napi_value args[1];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 1) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));

    EditBoxHandler::getInstance()->onTextInputBeginEvent(index, true, false);
//     native_manager::GetInstance()->TextInputEvent(index, true, false);
    return nullptr;
}

napi_value InputNapi::textInputOnChangeCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 2;
    napi_value args[2];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 2) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    status = napi_typeof(env, args[1], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_string) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));
    size_t pInt;
    char text[256];
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], text, 256, &pInt));

    EditBoxHandler::getInstance()->onTextInputEditingEvent(index, text) ;
    return nullptr;
}

napi_value InputNapi::textInputOnEnterCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 2;
    napi_value args[2];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 2) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    status = napi_typeof(env, args[1], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_string) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));
    size_t pInt;
    char text[256];
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], text, 256, &pInt));

    EditBoxHandler::getInstance()->onTextInputEnterEvent(index, false, true);
//     native_manager::GetInstance()->TextInputEvent(index, false, true);
    return nullptr;
}

napi_value InputNapi::textAreaOnBeginCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 1;
    napi_value args[1];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 1) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));

    EditBoxHandler::getInstance()->onTextAreaBeginEvent(index, true, false);
//     native_manager::GetInstance()->TextAreaEvent(index, true, false);
    return nullptr;
}

napi_value InputNapi::textAreaOnChangeCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 2;
    napi_value args[2];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 2) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    status = napi_typeof(env, args[1], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_string) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));
    size_t pInt;
    char text[256];
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], text, 256, &pInt));

    EditBoxHandler::getInstance()->onTextAreaEditingEvent(index, text);
//     native_manager::GetInstance()->TextAreaEditingEvent(index, text);
    return nullptr;
}

napi_value InputNapi::textAreaOnEnterCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 2;
    napi_value args[2];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 2) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_number) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    status = napi_typeof(env, args[1], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_string) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    int32_t index;
    NAPI_CALL(env, napi_get_value_int32(env, args[0], &index));
    size_t pInt;
    char text[256];
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[1], text, 256, &pInt));

    EditBoxHandler::getInstance()->onTextAreaEnterEvent(index, false, true);
    //     native_manager::GetInstance()->TextAreaEvent(index, false, true);
    return nullptr;
}

napi_value InputNapi::textFieldTTFOnChangeCB(napi_env env, napi_callback_info info) {

    napi_status status;
    size_t argc = 1;
    napi_value args[1];
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
    if (argc != 1) {
        napi_throw_type_error(env, NULL, "Wrong number of arguments");
        return nullptr;
    }

    napi_valuetype valuetype;
    status = napi_typeof(env, args[0], &valuetype);
    if (status != napi_ok) {
        return nullptr;
    }
    if (valuetype != napi_string) {
        napi_throw_type_error(env, NULL, "Wrong arguments");
        return nullptr;
    }

    //     const char* oldStr = cocos2d::IMEDispatcher::sharedDispatcher()->getContentText().c_str(); TODO
    const char *oldStr = "";
    size_t pInt;
    char text[256];
    NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], text, 256, &pInt));

    // 计算出差异位置
    int oldIndex = 0;
    int newIndex = 0;
    while (oldIndex < strlen(oldStr) && newIndex < strlen(text)) {
        if (oldStr[oldIndex] != text[newIndex]) {
            break;
        }
        oldIndex++;
        newIndex++;
    }

    // 删除原字符串差异位置之后的字符
    int oldLength = strlen(oldStr);
    for (; oldIndex < oldLength; oldIndex++) {
        //         cocos2d::IMEDispatcher::sharedDispatcher()->dispatchDeleteBackward(); TODO
    }

    // 截取新字符串差异位置后的部分，并插入
    if (strlen(text) > newIndex) {
        std::string newStr(text, sizeof(text));
        const char *modify = newStr.substr(newIndex).c_str();
        //         cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(modify, strlen(modify)); TODO
    }

    return nullptr;
}